#include <iostream>
#include <sys/stat.h>
#include <fcntl.h>
#include <dirent.h>
#include <unistd.h>
#include <string>
#include <vector>
#include <map>
using namespace std;

typedef multimap<string, int> SIMMAP;
SIMMAP allFileMap;

/* Get file_list recursively */
void GetListR(char * filep, vector<string> &file_list, const string &suffix = "") {
  DIR* pDir;
  struct dirent* myDirent;
  struct stat cur_stat;
  char allName[1024];
  if(!(pDir = opendir(filep)))
      cout<<"Open dir fail!"<< endl;
	while((myDirent = readdir(pDir)) != NULL)
	{
		if(strcmp(myDirent->d_name, ".") == 0 || strcmp(myDirent->d_name, "..") == 0)
		{
			continue;
		}
		memset(&cur_stat, 0, sizeof(cur_stat));
		memset(allName, 0, sizeof(allName));
		sprintf(allName, "%s/%s", filep, myDirent->d_name);
		lstat(allName, &cur_stat);
		if(cur_stat.st_mode & S_IFDIR)// If the current file is a sub-directory
		{
			GetListR(allName,file_list,suffix);
		}
    else if (cur_stat.st_mode & S_IFREG){ // If the current file is a regular file
        string fileName = allName;
        string fsuffix = fileName.substr(fileName.find_last_of('.') + 1);
        if (suffix == "" || strcmp(fsuffix.c_str(), suffix.c_str()) == 0)
            file_list.emplace_back(fileName);
        }
    else{
          cout<<"Not a file or a directory!"<<endl;
        }
}
}

/* Count lines for each file and save in a shared allFileMap */
void CountLine(string fileName, const string &suffix = "", bool blank_ignore=false){
        string fsuffix = fileName.substr(fileName.find_last_of('.') + 1);
        if (suffix == "" || strcmp(fsuffix.c_str(), suffix.c_str()) == 0)
				{
					int lineCnts = 0;
          int nblank_cnt = 0, blank_cnt = 0;
					ifstream ifs(fileName.c_str());
					if(!ifs.good())
					{
						return;
					}
					string str = "";
          string buf;
          while (getline(ifs, buf)) {
            buf.empty() ? blank_cnt++ : nblank_cnt++;
          }
          if (blank_ignore){
            lineCnts = nblank_cnt;
          }
          else
            lineCnts = nblank_cnt + blank_cnt + 1;
					allFileMap.insert(make_pair(fileName,lineCnts));
				}
}

/* Print allFileMap */
void PrintFileLine()
{ 
	SIMMAP::iterator it = allFileMap.begin();
  for(; it != allFileMap.end(); ++ it)
    // cout << it->second <<'\t'<< it->first << endl;
    printf("%4d\t%s\n", it->second, it->first.c_str());
}

/* Count all in allFileMap */
int GetAllLine()
{
	SIMMAP::iterator it = allFileMap.begin();
	int allLines = 0;
	for(; it != allFileMap.end(); ++ it)
	{
		allLines += it->second;
	}
	return allLines;
}
